﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.OccupantAudit.Dto;
using Admin.NET.Core.Service;
using DocumentFormat.OpenXml.Office2016.Drawing.Command;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.StaticFiles;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
namespace Admin.NET.Application;

/// <summary>
/// 用户审核管理服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class OccupantAuditService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<OccupantAudit> _occupantAuditRep;
    private readonly SqlSugarRepository<Floor> _floorRep;
    private readonly SqlSugarRepository<House> _house;
    private readonly SqlSugarRepository<Unit> _unitRep;
    private readonly SqlSugarRepository<Community> _communityRep;
    private readonly SqlSugarRepository<Buildings> _buildingRep;
    private readonly SqlSugarRepository<UserManagement> _manageRep;
    public OccupantAuditService(SqlSugarRepository<OccupantAudit> occupantAuditRep, SqlSugarRepository<House> house, SqlSugarRepository<Floor> floorRep, SqlSugarRepository<Unit> unitRep, SqlSugarRepository<Community> communityRep, SqlSugarRepository<Buildings> buildingRep, SqlSugarRepository<UserManagement> manageRep)
    {
        _occupantAuditRep = occupantAuditRep;
        _house = house;
        _floorRep = floorRep;
        _unitRep = unitRep;
        _communityRep = communityRep;
        _buildingRep = buildingRep;
        _manageRep = manageRep;
    }


    //http://xxxxxx.com/api/user/query/9/abc/123
    //http://xxxxxx.com/api/user/query/{id}/{keyword}/{aid}

    /// <summary>
    /// 分页查询用户审核管理
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
   // [HttpPost]
   // [ApiDescriptionSettings(Name = "Page")]
   // [DisplayName("分页查询用户审核管理")]
   // public async Task<SqlSugarPagedList<OccupantAuditOutput>> Page(PageOccupantAuditInput input)
   // {
	//	
   // }
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询用户审核管理")]
    public async Task<SqlSugarPagedList<OccupantAuditOutput>> Page(PageOccupantAuditInput input)
    {
        var query = (from occ in await _occupantAuditRep.GetListAsync()
                     join house in await _house.GetListAsync()
                     on occ.OccupantAddress equals house.Id
                     join floor in await _floorRep.GetListAsync()
                     on house.floorId equals floor.Id
                     join unit in await _unitRep.GetListAsync()
                     on floor.unitId equals unit.Id
                     join build in await _buildingRep.GetListAsync()
                     on unit.buildingsId equals build.Id
                     join com in await _communityRep.GetListAsync()
                     on build.communityId equals com.Id
                     where 
                     occ.OccupantAuditStatus == input.OccStatus 
                     select new OccupantAuditOutput
                     {
                         OccupantAddress = com.CommunityName + build.buildingsName + unit.unitName + floor.floorName + house.houseName,
                         Id = occ.Id,
                         OccupantExpirationTime = occ.OccupantExpirationTime,
                         OccupantName = occ.OccupantName,
                         OccupantAuditStatus = occ.OccupantAuditStatus,
                         OccupantNo = occ.OccupantNo,
                         OccupantGender = occ.OccupantGender == false ? "男" : "女",
                         OccupantPhone = occ.OccupantPhone,
                         OccupantTime = occ.OccupantTime,
                         OccupantType = occ.OccupantType
                     });
        if (!string.IsNullOrEmpty(input.OccupantAddress))
        {
            query = query.Where(u => u.OccupantAddress.Contains(input.OccupantAddress));
        }
        if (!string.IsNullOrEmpty(input.OccupantName))
        {
            query = query.Where(u => u.OccupantName.Contains(input.OccupantName));
        }
        if (!string.IsNullOrEmpty(input.OccupantPhone))
        {
            query = query.Where(u => u.OccupantPhone.Contains(input.OccupantPhone));
        }
        if (input.OccupantType != 0 && input.OccupantType > 0)
        {
            query = query.Where(u => u.OccupantType == input.OccupantType);
        }
        int totalCount = query.Count();
        query = query.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize);
        return new SqlSugarPagedList<OccupantAuditOutput>()
        {
            Items = query,
            Total = totalCount,
        };


    }

    /// <summary>
    /// 增加用户审核管理
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加用户审核管理")]
    public async Task<long> Add(AddOccupantAuditInput input)
    {
        var entity = input.Adapt<OccupantAudit>();
        await _occupantAuditRep.InsertAsync(entity);
        return entity.Id;
    }

    /// <summary>
    /// 删除用户审核管理
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除用户审核管理")]
    public async Task Delete(DeleteOccupantAuditInput input)
    {
        var entity = await _occupantAuditRep.GetFirstAsync(u => u.Id == input.OccupantAuditId) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _occupantAuditRep.FakeDeleteAsync(entity);   //假删除
        //await _occupantAuditRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新用户审核管理
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新用户审核管理")]
    public async Task Update(UpdateOccupantAuditInput input)
    {
        var entity = input.Adapt<OccupantAudit>();
        await _occupantAuditRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取用户审核管理
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取用户审核管理")]
    public async Task<OccupantAudit> Detail(int OccupantAuditId,long Id)
    {
        return await _occupantAuditRep.GetFirstAsync(u => u.Id == OccupantAuditId);
    }

    /// <summary>
    /// 获取用户审核管理列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取用户审核管理列表")]
    public async Task<List<OccupantAuditOutput>> List([FromQuery] PageOccupantAuditInput input)
    {
        return await _occupantAuditRep.AsQueryable().Select<OccupantAuditOutput>().ToListAsync();
    }
    /// <summary>
    /// 获取用户审核管理详情
    /// </summary>
    /// <param name="id">主键Id</param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "GetOccById")]
    [DisplayName("获取用户审核管理详情")]
    public async Task<RusultDTO<GetOccByIdDTO>> GetOccById([FromQuery]int id)
    {
        string[] occtype = { "业主", "租户", "快递", "业主家属", "物业人员", "公司" };
        var query = (from occ in await _occupantAuditRep.GetListAsync()
                     join house in await _house.GetListAsync()
                     on occ.OccupantAddress equals house.Id
                     join floor in await _floorRep.GetListAsync()
                     on house.floorId equals floor.Id
                     join unit in await _unitRep.GetListAsync()
                     on floor.unitId equals unit.Id
                     join build in await _buildingRep.GetListAsync()
                     on unit.buildingsId equals build.Id
                     join com in await _communityRep.GetListAsync()
                     on build.communityId equals com.Id
                     where !occ.IsDelete &&
                     !house.IsDelete &&
                     !floor.IsDelete &&
                     !unit.IsDelete &&
                     !com.IsDelete &&
                     !build.IsDelete
                     select new GetOccByIdDTO
                     {
                         OccupantAddress = com.CommunityName + build.buildingsName + unit.unitName + floor.floorName + house.houseName,
                         Id = occ.Id,
                         OccupantExpirationTime = occ.OccupantExpirationTime,
                         OccupantName = occ.OccupantName,
                         OccupantNo = occ.OccupantNo,
                         OccupantGender = occ.OccupantGender == false ? "男" : "女",
                         OccupantPhone = occ.OccupantPhone,
                         OccupantTime = occ.OccupantTime,
                         OccupantType = occtype[(int)(occ.OccupantType - 1)]
                     }).FirstOrDefault(t => t.Id == id);
        return new RusultDTO<GetOccByIdDTO>()
        {
            code = 200,
            data = query,
            msg = null
        };
    }
    /// <summary>
    /// 修改住户状态
    /// </summary>
    /// <param name="input">修改字段</param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "UpdateStatus")]
    [DisplayName("修改住户状态")]
    public async Task<RusultDTO<UdpateOccStatusDTO>> UpdateOccStatus(UpdateOccStatusInput input)
    {
        var entity = await _occupantAuditRep.GetFirstAsync(t => t.Id == input.Id);
        entity.OccupantAuditStatus = input.OccupantStatus;
        entity.OccupantExpirationTime = input.OccupantExpirationTime;
        entity.OccupantTime = DateTime.Now;
        UdpateOccStatusDTO dto = new UdpateOccStatusDTO();
        var s = await _occupantAuditRep.UpdateAsync(entity);
        if (s)
        {
            if (input.OccupantStatus == 1)
            {
                dto.code = 200;
                dto.msg = "审核通过！";
            }
            if (input.OccupantStatus == 2)
            {
                dto.code = 200;
                dto.msg = "驳回成功！";
            }
            if (input.OccupantStatus == 3)
            {
                dto.code = 200;
                dto.msg = "迁出成功！";
            }
        }
        return new RusultDTO<UdpateOccStatusDTO>()
        {
            code = 200,
            data = dto,
            msg = null
        };
    }
    /// <summary>
    /// 修改住户字段
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "UpdateOccEvery")]
    [DisplayName("修改住户字段")]
    public async Task<RusultDTO<UdpateOccStatusDTO>> UpdateOccEvery(UpdateOccEveryInput input)
    {
        var entity = await _occupantAuditRep.GetFirstAsync(t => t.Id == input.Id);
        entity.OccupantName = input.OccupantName;
        entity.OccupantPhone = input.OccupantPhone;
        entity.OccupantGender = input.OccupantGender;
        entity.OccupantAddress = input.OccupantAddress;
        entity.OccupantNo = input.OccupantNo;
        entity.OccupantType = input.OccupantType;
        entity.OccupantExpirationTime = input.OccupantExpirationTime;
        entity.OccupantTime = DateTime.Now;
        UdpateOccStatusDTO dto = new UdpateOccStatusDTO();
        var s = await _occupantAuditRep.UpdateAsync(entity);
        if (s)
        {
            dto.code = 200;
            dto.msg = "修改成功！";
        }
        else
        {
            dto.code = 500;
            dto.msg = "修改失败！";
        }
        return new RusultDTO<UdpateOccStatusDTO>()
        {
            code = 200,
            data = dto,
            msg = null
        };
    }
    /// <summary>
    /// 绑定房屋下拉框
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "BindHouse")]
    [DisplayName("绑定房屋下拉框")]
    public async Task<object> BindHouse()
    {
        var query = (from house in await _house.GetListAsync()
                     join floor in await _floorRep.GetListAsync()
                     on house.floorId equals floor.Id
                     join unit in await _unitRep.GetListAsync()
                     on floor.unitId equals unit.Id
                     join build in await _buildingRep.GetListAsync()
                     on unit.buildingsId equals build.Id
                     join com in await _communityRep.GetListAsync()
                     on build.communityId equals com.Id
                     select new BindHouseOutput
                     {
                         Id=house.Id,
                         Address= com.CommunityName + build.buildingsName + unit.unitName + floor.floorName + house.houseName
                     });
        return query.ToList();
    }
    /// <summary>
    /// 导出
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Excel")]
    [DisplayName("导出")]
    public async Task<ActionResult> GetExcel(PageOccupantAuditInput input)
    {
        string[] occtype = { "业主", "租户", "快递", "业主家属", "物业人员", "公司" };
        using (IWorkbook book=new XSSFWorkbook())
        {
            ISheet sheet = book.CreateSheet();
            IRow headerRow = sheet.CreateRow(0);
            headerRow.CreateCell(0).SetCellValue("姓名");
            headerRow.CreateCell(1).SetCellValue("身份证号");
            headerRow.CreateCell(2).SetCellValue("房间");
            headerRow.CreateCell(3).SetCellValue("性别");
            headerRow.CreateCell(4).SetCellValue("电话");
            headerRow.CreateCell(5).SetCellValue("提交时间");
            headerRow.CreateCell(6).SetCellValue("有效期限");
            headerRow.CreateCell(7).SetCellValue("住户类型");
            var query = Page(input).Result.Items;
            int index = 1;
            foreach(var i in query)
            {
                IRow dataRow = sheet.CreateRow(index);
                dataRow.CreateCell(0).SetCellValue(i.OccupantName);
                dataRow.CreateCell(1).SetCellValue(i.OccupantNo);
                dataRow.CreateCell(2).SetCellValue(i.OccupantAddress);
                dataRow.CreateCell(3).SetCellValue(i.OccupantGender);
                dataRow.CreateCell(4).SetCellValue(i.OccupantPhone);
                dataRow.CreateCell(5).SetCellValue(i.OccupantTime.Value.ToString("yyyy-MM-dd HH:mm:ss"));
                dataRow.CreateCell(6).SetCellValue(i.OccupantExpirationTime);
                dataRow.CreateCell(7).SetCellValue(occtype[(int)i.OccupantType - 1]);
                index++;
            }
            using (MemoryStream ms = new MemoryStream())
            {
                book.Write(ms);
                byte[] bytes = ms.ToArray();
                string contentType=new FileExtensionContentTypeProvider().Mappings[".xlsx"];
                string fileName = "住户信息" + DateTime.Now.ToString("yyyyMMHHmmss") + ".xlsx";
                return new FileStreamResult(new MemoryStream(bytes), contentType)
                {
                    FileDownloadName=fileName
                };

            }

        }
    }
    /// <summary>
    /// 分页显示用户
    /// </summary>
    /// <param name="input">输入类</param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "GetUserManager")]
    [DisplayName("分页获取用户")]
    public async Task<SqlSugarPagedList<PageGetUserManagerOutput>> PageGetUserManager(PageGetUserManagerInput input)
    {
        var query = (from manage in await _manageRep.GetListAsync()
                     join occ in await _occupantAuditRep.GetListAsync()
                     on manage.OccupantAuditId equals occ.Id
                     where manage.UserStatus==input.UserStatus
                     select new PageGetUserManagerOutput
                     {
                         Id = manage.Id,
                         OccType = occ.OccupantType,
                         UserGender = manage.UserGender,
                         UserName = manage.UserName,
                         UserNo = manage.UserNo,
                         UserPhone = manage.UserPhone,
                         UserStatus = manage.UserStatus,
                         UserTime = manage.UserManagementTime,
                     });
        if (!string.IsNullOrEmpty(input.UserName))
        {
            query=query.Where(t=>t.UserName.Contains(input.UserName));
        }
        if (!string.IsNullOrEmpty(input.UserPhone))
        {
            query = query.Where(t => t.UserPhone.Contains(input.UserPhone));
        }
        if(!string.IsNullOrEmpty(input.StartTime)||!string.IsNullOrEmpty(input.EndTime))
        {
            if (!string.IsNullOrEmpty(input.StartTime))
            {
                query = query.Where(t => t.UserTime >= DateTime.Parse(input.StartTime));
            }
            if (!string.IsNullOrEmpty(input.EndTime))
            {
                query = query.Where(t => t.UserTime <= DateTime.Parse(input.EndTime));
            }
            if (!string.IsNullOrEmpty(input.StartTime) && !string.IsNullOrEmpty(input.EndTime))
            {
                query = query.Where(t => t.UserTime >= DateTime.Parse(input.StartTime) && t.UserTime <= DateTime.Parse(input.EndTime));
            }
        }
        int total = query.Count();
        query = query.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize);
        return new SqlSugarPagedList<PageGetUserManagerOutput>()
        {
            Items=query,
            Total=total,
        };
    }
    /// <summary>
    /// 反填用户
    /// </summary>
    /// <param name="id">主键Id</param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "GetUserById")]
    [DisplayName("反填用户")]
    public async Task<RusultDTO<GetUserByIdOutput>> GetUserById([FromQuery]int id)
    {
        var query = (from manage in await _manageRep.GetListAsync()
                     join occ in await _occupantAuditRep.GetListAsync()
                     on manage.OccupantAuditId equals occ.Id
                     select new GetUserByIdOutput
                     {
                         Id = manage.Id,
                         OccType = occ.OccupantType,
                         UserGender = manage.UserGender,
                         UserName = manage.UserName,
                         UserNo = manage.UserNo,
                         UserPhone = manage.UserPhone,
                         UserStatus = manage.UserStatus,
                         UserTime = manage.UserManagementTime,
                         ExtionTime=occ.OccupantExpirationTime
                     }).FirstOrDefault(t=>t.Id==id);
        return new RusultDTO<GetUserByIdOutput>
        {
            code = 200,
            data=query,
            msg = null
        };
    }
    [HttpPost]
    [ApiDescriptionSettings(Name = "UpdateUserStatus")]
    [DisplayName("审核用户状态")]
    public async Task<RusultDTO<UdpateOccStatusDTO>> UpdateUserStatus(UpdateUserStatusInput input)
    {
        var query = _manageRep.GetById(input.Id);
        query.UserStatus = input.Status;
        query.UserManagementTime = DateTime.Now;
        var s = await _manageRep.UpdateAsync(query);
        RusultDTO < UdpateOccStatusDTO > dto=new RusultDTO<UdpateOccStatusDTO>();
        if (s)
        {
            if (input.Status == 1)
            {
                dto.msg = "审核通过！";
                dto.code = 200;
            }
            if (input.Status == 2)
            {
                dto.msg = "驳回成功！";
                dto.code = 200;
            }
        }
        return dto;
    }
    /// <summary>
    /// 导出
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "GetUserExcel")]
    [DisplayName("用户导出")]
    public async Task<ActionResult> GetUserExcel(PageGetUserManagerInput input)
    {
        string[] occtype = { "业主", "租户", "快递", "业主家属", "物业人员", "公司" };
        using (IWorkbook book = new XSSFWorkbook())
        {
            ISheet sheet = book.CreateSheet();
            IRow headerRow = sheet.CreateRow(0);
            headerRow.CreateCell(0).SetCellValue("姓名");
            headerRow.CreateCell(1).SetCellValue("身份证号");
            headerRow.CreateCell(2).SetCellValue("住户类型");
            headerRow.CreateCell(3).SetCellValue("性别");
            headerRow.CreateCell(4).SetCellValue("电话");
            headerRow.CreateCell(5).SetCellValue("提交时间");
            var query = PageGetUserManager(input).Result.Items;
            int index = 1;
            foreach (var i in query)
            {
                IRow dataRow = sheet.CreateRow(index);
                dataRow.CreateCell(0).SetCellValue(i.UserName);
                dataRow.CreateCell(1).SetCellValue(i.UserNo);
                dataRow.CreateCell(2).SetCellValue(occtype[(int)i.OccType-1]);
                dataRow.CreateCell(3).SetCellValue(i.UserGender==false?"男":"女");
                dataRow.CreateCell(4).SetCellValue(i.UserPhone);
                dataRow.CreateCell(5).SetCellValue(i.UserTime.Value.ToString("yyyy-MM-dd HH:mm:ss"));
                index++;
            }
            using (MemoryStream ms = new MemoryStream())
            {
                book.Write(ms);
                byte[] bytes = ms.ToArray();
                string contentType = new FileExtensionContentTypeProvider().Mappings[".xlsx"];
                string fileName = "用户信息" + DateTime.Now.ToString("yyyyMMHHmmss") + ".xlsx";
                return new FileStreamResult(new MemoryStream(bytes), contentType)
                {
                    FileDownloadName = fileName
                };

            }

        }
    }


}
